import datetime
import random
from app.libs.yuntongxun.sms import CCP
from app import redis_store, constants, db
from app.models import User
from app.utils.response_code import RET
from . import passport_blu
from flask import request, current_app, make_response, jsonify, session
from app.utils.captcha.captcha import captcha
import re


@passport_blu.route('/logout', methods=['POST'])
def logout():
    session.pop("userid")
    session.pop("mobile")
    session.pop("nick_name")
    session.pop("is_admin")
    return jsonify(errno=RET.OK, errmsg="OK")


# 登陆实现
@passport_blu.route('/login', methods=['POST'])
def login():
    """
    思路分析:
    1.获取参数
    2.校验参数
    3.根据手机号取出用户对象
    4.判断密码正确性
    5.将用户的登陆信息存到session
    6.返回响应
    :return:
    """
    dic_data = request.json
    mobile = dic_data.get("mobile")
    password = dic_data.get("password")
    if not all([mobile, password]):
        return jsonify(errno=RET.PARAMERR, errmsg="输入有误")
    try:
        user = User.query.filter(User.mobile == mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库无法获取用户数据")
    if not user:
        return jsonify(errno=RET.DATAERR, errmsg="用户不存在")
    if not user.check_passowrd(password):
        return jsonify(errno=RET.PWDERR, errmsg="密码错误")
    session["userid"] = user.id
    session["name"] = user.nick_name
    session["mobile"] = user.mobile
    session["is_admin"] = (user.is_admin==1)
    user.last_login = datetime.datetime.now()
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
    return jsonify(errno=RET.OK, errmsg="OK")


# 注册实现
@passport_blu.route('/register', methods=['POST'])
def register():
    dic_data = request.json
    mobile = dic_data.get("mobile")
    smscode = dic_data.get("smscode")
    password = dic_data.get("password")

    #     空值判定
    if not all([mobile, smscode, password]):
        return jsonify(errno=RET.PARAMERR, errmsg="输入有误")
    if not re.match('1[345678]\\d{9}', mobile):
        return jsonify(errno=RET.DATAERR, errmsg="手机号格式有误")
    try:
        sms_code = redis_store.get("sms_code:%s" % mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库获取短信验证码失败")
    if not sms_code:
        return jsonify(errno=RET.NODATA, errmsg="短信验证码过期")
    if sms_code != smscode:
        return jsonify(errno=RET.DATAERR, errmsg="短信验证码错误")
    try:
        redis_store.delete("sms_code:%s" % mobile)
    except Exception as e:
        current_app.logger.error(e)

    user = User(nick_name=mobile, mobile=mobile)
    user.password = password

    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="mysql存储出错")
    session["userid"] = user.id
    session["name"] = user.nick_name
    session["mobile"] = user.mobile
    session["is_admin"] = (user.is_admin==1)
    return jsonify(errno=RET.OK, errmsg="OK")


# 验证短信
@passport_blu.route('/sms_code', methods=['POST'])
def send_message():
    """
       思路分析:
       1.接收参数
       2.校验参数,为空校验
       3.校验手机号格式是否正确
       4.通过验证码编号,取出图片验证码A
       5.判断验证码A是否过期
       6.判断图片验证码是否正确
       7.调用CCP发送短信方法
       8.判断短信是否发送成功
       9.保存短信到redis中
       10.返回发送的状态
       :return:
    """
    # 从请求中获取参数
    dic_data = request.json
    mobile = dic_data.get("mobile")
    image_code = dic_data.get("image_code")
    image_code_id = dic_data.get("image_code_id")

    if not all([mobile, image_code, image_code_id]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")
    if not re.match("^1[345678][0-9]{9}$", mobile):
        return jsonify(errno=RET.DATAERR, errmsg="手机号码不正确")
    try:
        redis_image_code = redis_store.get("image_code:%s" % image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库读取数据出错")
    if not redis_image_code:
        return jsonify(errno=RET.DATAERR, errmsg="验证码已过期")
    if not (image_code.upper() == redis_image_code.upper()):
        return jsonify(errno=RET.DATAERR, errmsg="验证失败")
    sms_code = "%06d" % random.randint(0, 999999)
    # 记录验证码
    current_app.logger.error("短信验证码 = %s" % sms_code)
    # try:
    #     cpp = CCP()
    #     result = cpp.send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES / 60], 1)
    # except Exception as e:
    #     current_app.logger.error(e)
    #     return jsonify(errno=RET.THIRDERR, errmsg="云通讯出错")
    #
    # if result == -1:
    #     return jsonify(errno=RET.DATAERR, errmsg="短信发送失败")
    #  存入redis
    try:
        redis_store.set("sms_code:%s" % mobile, sms_code, constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="短信验证码存储失败")

    return jsonify(errno=RET.OK, errmsg="短信验证成功")


# 验证码
@passport_blu.route('/image_code')
def get_image_code():
    # 从请求中获取参数
    cur_id = request.args.get("cur_id")  # 当前图片验证码
    pre_id = request.args.get('pre_id')  # 前一个图片验证码
    # 生成图片验证码
    _, text, image_data = captcha.generate_captcha()
    # 存到缓存中redis
    try:
        redis_store.set("image_code:%s" % cur_id, text, constants.IMAGE_CODE_REDIS_EXPIRES)
        # 确保图片的单例
        if pre_id:
            redis_store.delete("image_code:%s" % pre_id)
    except Exception as e:
        current_app.logger.error(e)
        return make_response(jsonify(errno=RET.DATAERR, errmsg='保存图片验证码失败'))
    # 响应体
    response = make_response(image_data)
    response.headers["Content_Type"] = "imag/jpg"
    return response
